package org.rc.server;


import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.rc.cache.FrontTextSessionCache;
import org.rc.cache.PersonnelNameCache;
import org.rc.cache.RoleTextClientCache;
import org.rc.cache.SlpTextSessionCache;
import org.rc.client.SwRoleTextClient;
import org.rc.component.DtComponent;
import org.rc.config.WsSessionConfig;
import org.rc.dto.FrontCommandDto;
import org.rc.dto.KeyWordGroup;
import org.rc.entity.Mic;
import org.rc.entity.RoomDev;
import org.rc.entity.Slp;
import org.rc.enums.DevType;
import org.rc.service.*;
import org.rc.util.BusinessTool;
import org.rc.util.RequestParamUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.net.URI;
import java.util.List;
import java.util.Map;

/**
 * 受令屏和服务的的ws连接
 */
@Slf4j
@ServerEndpoint(value = "/audio-text",configurator = WsSessionConfig.class)
@Component
@Scope("prototype")
public class AudioTextEndpoint {

    @Autowired
    RoomDevService roomDevService;

    @Autowired
    private DtComponent dtComponent;

    @Autowired
    SlpService slpService;

    @Autowired
    MicService micService;

    @Value("${alarm.keyWord.url}")
    private String alarmKeyWordUrl;

    @Value("${sw.role.text.endpoint}")
    private String swRoleTextEndpoint;

    @Autowired
    private ConversationTextService conversationTextService;

    @Autowired
    private PersonnelNameCache personnelNameCache;

    @OnOpen
    public void onOpen(Session session, EndpointConfig config) throws IOException{
        String param = session.getQueryString();
        Map<String,String> paramsMap = RequestParamUtil.regularParam2Map(param);
        String mac = paramsMap.get("mac");
        String recordId = paramsMap.get("recordId");
        log.info("接收到受令屏请求，mac--->{},recordId--->{}",mac,recordId);
        if(StringUtils.isEmpty(mac)){
            log.warn("请求连接时，mac地址为空,关闭连接");
            session.getBasicRemote().sendText("请求连接时，mac地址不能为空");
            session.close();
            return;
        }
        mac = BusinessTool.handleMac(mac);

        //根据受令屏mac地址查询受令屏信息
        Slp slp = slpService.getSlpByMac(mac);
        if(null == slp){
            log.warn("根据mac地址查询受令屏为空,关闭连接");
            session.getBasicRemote().sendText("根据mac地址查询受令屏为空");
            session.close();
            return;
        }
        //根据受令屏id获取绑定房间对应的麦克风mac
        RoomDev roomSlp = roomDevService.getRoomDevByTypeAndDevId(DevType.SLP.getType(), slp.getId());
        if(null == roomSlp){
            log.warn("受令屏尚未在系统中绑定房间,关闭连接");
            session.getBasicRemote().sendText("受令屏尚未在系统中绑定房间");
            session.close();
            return;
        }

        List<RoomDev> roomMic =roomDevService.getRoomDevByRoomIdAndDevId(DevType.MIC.getType(), roomSlp.getRoomId());
        if(CollectionUtils.isEmpty(roomMic)){
            log.warn("受令屏所在房间尚未绑定麦克风,关闭连接");
            session.getBasicRemote().sendText("受令屏所在房间尚未绑定麦克风");
            session.close();
            return;
        }

        Mic mic = micService.getByMicId(roomMic.get(0).getDevId());
        String micMac = mic.getMac();
        session.getUserProperties().put("mac",micMac);

        log.info("当前麦克风--->{},无拉取文本连接，开始建立连接。",micMac);
        List<KeyWordGroup> keyWordDic = dtComponent.getKeyWordDic();
        log.debug("获取到关键词预警配置--->{}",JSONObject.toJSONString(keyWordDic));
        try{
            URI uri = new URI(swRoleTextEndpoint+"?devId="+micMac);
            SwRoleTextClient swRoleTextClient =new SwRoleTextClient(uri,micMac,conversationTextService,keyWordDic,personnelNameCache.getNames(),Long.parseLong(recordId));
            RoleTextClientCache.saveClient(micMac,swRoleTextClient);
        }catch (Exception e){
            log.error("与声纹角色分离服务建立连接异常,e--->",e);
        }
        SlpTextSessionCache.add(micMac,session);
    }

    @OnMessage
    public void onMessage(String text, Session session) throws IOException {
        String mac = session.getUserProperties().get("mac").toString();
        if(StringUtils.isNotEmpty(text) && !"heartBeat".equals(text)){
            log.info("接收到受令屏发出的指令--->{}",text);
            FrontCommandDto frontTextDto = new FrontCommandDto("command",text);
            FrontTextSessionCache.sendText(mac,JSONObject.toJSONString(frontTextDto));
        }
    }

    @OnClose
    public void onClose(Session session){
        String mac = session.getUserProperties().get("mac").toString();
        log.info("受令屏断开连接，mac--->{}",mac);
        SlpTextSessionCache.removeSession(mac);
        RoleTextClientCache.delClient(mac);
    }

    @OnError
    public void onError(Session session, Throwable th){
        String mac = session.getUserProperties().get("mac").toString();
        log.error("受令屏连接发生异常，mac--->"+mac+"e--->",th);
        SlpTextSessionCache.removeSession(mac);
        RoleTextClientCache.delClient(mac);
    }

}
